/**
 * 深拷贝
 * @param {Object} obj
 * @returns {Object}
 */
export function deepClone(obj) {
  const objClone = Array.isArray(obj) ? [] : {}
  if (obj && typeof obj === 'object') {
    for (const key in obj) {
      // eslint-disable-next-line no-prototype-builtins
      if (obj.hasOwnProperty(key)) {
        // 判断ojb子元素是否为对象，如果是，递归复制
        if (obj[key] && typeof obj[key] === 'object') {
          objClone[key] = deepClone(obj[key])
        } else {
          // 如果不是，简单复制
          objClone[key] = obj[key]
        }
      }
    }
  }
  return objClone
}

/**
 * 迭代器
 * @param {list} list
 * @returns {list}
 */
export function iteratorGenerator(list) {
  let idx = 0
  const length = list.length

  return {
    // 定义next 方法
    next: function () {
      // 判断索引是否超出集合长度
      const done = idx >= length
      const value = !done ? list[idx++] : undefined

      return {
        done: done,
        value: value,
      }
    },
  }
}

/**
 * 节流，在某段时间内，不管触发多少次回调，只认第一次，并在计时结束时给予响应
 * const better_scroll = throttle(() => console.log('触发了滚动事件'), 1000)
 * document.addEventListener('scroll', better_scroll)
 */
export function throttle(fn, interval) {
  let last = 0

  return function () {
    const context = this
    const args = arguments
    const now = +new Date()

    if (now - last > interval) {
      last = now
      fn.apply(context, args)
    }
  }
}

/**
 * 防抖，在某段时间内，不管触发多少次回调，只认最后一次
 * 为防止不断触发一直没有回应，设置一个最长等待时间，在最长等待时间结束后一定给予响应
 * const better_scroll = throttle(() => console.log('触发了滚动事件'), 1000)
 * document.addEventListener('scroll', better_scroll)
 */
export function debounce(fn, delay) {
  let last = 0
  let timer = null

  return function () {
    const context = this
    const args = arguments
    const now = +new Date()

    if (now - last < delay) {
      clearTimeout(timer)
      timer = setTimeout(() => {
        last = now
        fn.apply(context, args)
      }, delay)
    } else {
      last = now
      fn.apply(context, args)
    }
  }
}
